package com.pn.service.impl;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pn.mapper.SysMenuMapper;
import com.pn.entity.SysMenu;
import com.pn.service.SysMenuService;
import org.springframework.util.StringUtils;

@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService{

    //注入SysMenuMapper
    @Autowired
    private SysMenuMapper menuMapper;

    //注入redis模板
    @Autowired
    private StringRedisTemplate redisTemplate;

    /*
      查询用户权限菜单树的业务方法
      1.先从redis中查询缓存的菜单树List<SysMenu>,如果有将菜单树List<SysMenu>转的json串转回菜单树List<SysMenu>并返回;
        (放入redis缓存中的用户权限菜单树的键menu:userId,值是用户的菜单树List<SysMenu>转的json串)
      2.如果没有,则先从数据库表中查出所有菜单List<SysMenu>,然后将所有菜单List<SysMenu>转成菜单树List<SysMenu>,
        再然后将菜单树List<SysMenu>缓存到redis,最后再返回;
     */
    @Override
    public List<SysMenu> menuTreeByUid() {
        //拿到当前登录的用户id -- 其实是拿当前登录的用户名的,而我们返回的是用户id
        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();

        //从redis中查询缓存的菜单树List<SysMenu>
        String menuTreeListJson = redisTemplate.opsForValue().get("menu:" + userId);

        /*
          redis中有缓存
         */
        if(StringUtils.hasText(menuTreeListJson)){
            //将json串转回菜单树List<SysMenu>并返回
            List<SysMenu> menuTreeList = JSON.parseArray(menuTreeListJson, SysMenu.class);
            return menuTreeList;
        }

        /*
          redis中没有缓存
         */
        //查询当前登录的用户的所有菜单
        List<SysMenu> allMenuList = menuMapper.findAllMenuByUid(Long.parseLong(userId));
        //将用户所有菜单List<SysMenu>转成菜单树List<SysMenu>
        List<SysMenu> menuTreeList = allMenuToMenuTree(allMenuList, 0L);
        //将菜单树List<SysMenu>缓存到redis
        redisTemplate.opsForValue().set("menu:" + userId, JSON.toJSONString(menuTreeList));
        return menuTreeList;
    }

    //将所有菜单List<SysMenu>转成菜单树List<SysMenu>的递归算法
    private List<SysMenu> allMenuToMenuTree(List<SysMenu> allMenuList, Long pid){

        List<SysMenu> firstLevelMenus = new ArrayList<>();
        for (SysMenu sysMenu : allMenuList) {
            if(sysMenu.getParentId().equals(pid)){
                firstLevelMenus.add(sysMenu);
            }
        }

        for (SysMenu sysMenu : firstLevelMenus) {
            List<SysMenu> secondLevelMenus = allMenuToMenuTree(allMenuList, sysMenu.getMenuId());
            sysMenu.setList(secondLevelMenus);
        }

        return firstLevelMenus;
    }
}
